package com.tang.basics.introductory;

/**
 * 运算符介绍
 * 运算符是一种特殊的符号，用以表示数据的运算、赋值和比较等。
 * 1) 算术运算符 2) 赋值运算符 3) 关系运算符 [比较运算符] 4) 逻辑运算符 5) 位运算符 [需要二进制基础] 6) 三元运算符
 */
public class Operator_09 {
    public static void main(String[] args) {
//        ArithmeticOperator.demo();
//        ArithmeticOperatorExercise01.demo();
//        ArithmeticOperatorExercise02.demo();
//        RelationalOperator.demo();
//        LogicalOperator.InverseOperator();
        TernaryOperator.Detail();
    }
}

/*
 * 算术运算符介绍：
 * １.算术运算符是对数值类型的变量进行运算的
 * 2.概览
 * + 正号　　      >>> +7       = 7
 * - 负号         >>> b=7;-b   = -7
 * + 加号         >>> 9+9      = 18
 * - 减号         >>> 10-8     = 8
 * * 乘号         >>> 2*2      = 4
 * / 除号         >>> 9/9      = 1
 * % 取模（取余)   >>> 11%9     = 2             =11 % 9 = 11 - 11 / 9 * 9 =2
 * ++ 自增（前）：先运算后取值    >>> a=2;b=++a    = a=3;b=3
 * ++ 自增（后）：先取值后运行　　 >>> a=2;b=a++    = a=3;b=2
 * -- 自增（前）：先运算后取值    >>>  a=2;b=--a   = a=1;b=1
 * -- 自增（后）：先取值后运行　　 >>> a=2;b=a--    = a=1;b=2
 * */
class ArithmeticOperator {
    public static void demo() {
        System.out.println(10 / 4); //从数学来看是 2.5, java 中 2
        System.out.println(10.0 / 4); //java 是 2.5
        double d = 10 / 4;//java 中 10 / 4 = 2, 2=>2.0
        System.out.println(d);// 是 2.0
        // % 取模 ,取余
        // 在 % 的本质 看一个公式!!!! a % b = a - a / b * b
        // -10 % 3 => -10 - (-10) / 3 * 3 = -10 + 9 = -1
        //  10 % -3 = 10 - 10 / (-3) * (-3) = 10 - 9 = 1
        // -10 % -3 = (-10) - (-10) / (-3) * (-3) = -10 + 9 = -1
        System.out.println(10 % 3); //1
        System.out.println(-10 % 3); // -1
        System.out.println(10 % -3); //1
        System.out.println(-10 % -3);//-1
        //++的使用
        int i = 10;
        i++;//自增 等价于 i = i + 1; => i = 11
        ++i;//自增 等价于 i = i + 1; => i = 12
        System.out.println("i=" + i);//12
        /*作为表达式使用 前++：++i 先自增后赋值 后++：i++先赋值后自增 */
        int j = 8;
        //int k = ++j; //等价 j=j+1;k=j;
        int k = j++; // 等价 k =j;j=j+1;
        System.out.println("k=" + k + "j=" + j);//8 9

        int ii = 1; //=1
        ii = ii++; //temp=i   i=temp+1  i=temp  1
        //ii = ++ii; //i=i+1   i=temp   i=temp  2
        System.out.println(ii);//1

    }
}

//自增，自减课堂练习
class ArithmeticOperatorExercise01 {
    public static void demo() {
        // int i = 1;//i->1
        // i = i++; //规则使用临时变量: (1) temp=i;(2) i=i+1;(3)i=temp;
        // System.out.println(i); // 1
        // int i=1;
        // i=++i; //规则使用临时变量: (1) i=i+1;(2) temp=i;(3)i=temp;
        // System.out.println(i); //2
        // 测试输出
        int i1 = 10;
        int i2 = 20;
        int i = i1++;
        System.out.print("i=" + i);//10
        System.out.println("i2=" + i2);//20
        i = --i2;
        System.out.print("i=" + i);//19 i2= i2-1  temp=i2  i=temp
        System.out.println("i2=" + i2);//19 i2= i2-1
    }
}


//1) 假如还有 59 天放假，问：合 xx 个星期零 xx 天 2)
// 定义一个变量保存华氏温度，华氏温度转换摄氏温度的公式为：5/9*(华氏温度-100),
// 请求出华氏温度对应的摄氏温度。 [234.5]
class ArithmeticOperatorExercise02 {
    public static void demo() {
        //1.需求:
        // 假如还有 59 天放假，问：合 xx 个星期零 xx 天
        // 2.思路分析
        // (1) 使用 int 变量 days 保存 天数
        // (2) 一个星期是 7 天 星期数 weeks： days / 7 零 xx 天 leftDays days % 7 //(3) 输出

        int days = 59;
        int weeks = days / 7;
        int leftDays = days % 7;
        System.out.println(days + "天 合" + weeks + "星期零" + leftDays + "天");

        //定义一个变量保存华氏温度，华氏温度转换摄氏温度的公式为
        // ：5/9*(华氏温度-100),请求出华氏温度对应的摄氏温度

        //2 思路分析
        // (1) 先定义一个 double huaShi 变量保存 华氏温度
        // (2) 根据给出的公式，进行计算即可 5/9*(华氏温度-100)
        // 考虑数学公式和 java 语言的特性
        // (3) 将得到的结果保存到 double sheShi
        double huaShi = 1234.6;
        double sheShi = 5.0 / 9 * (huaShi - 100);
        System.out.println("华氏温度" + huaShi + " 对应的摄氏温度=" + sheShi);

    }
}



/*
 * 关系运算符(比较运算符)介绍：
 * 1.关系运算符的结果都是 boolean 型，也就是要么是 true，要么是 false
 * 2.关系表达式 经常用在 if 结构的条件中或循环结构的条件中
 * 3.关系运算符组成的表达式，我们称为关系表达式。 a > b
 * 4.概览
 * 运算符　　　运算　　　　范例　　　结果
 * ==    　　相等于　　　8==7     false
 * !=       不等于     8!=7     true
 * <        小于　　　　８<7      false
 * >        大于　　　　8>7       true
 * <=       小于等于　　8<=7      fales
 * >=       大于等于　　8>=7      true
 *
 * instanceof : 检查是否是类的对象
 * */

class RelationalOperator {
    public static void demo() {
        int a = 9;
        int b = 8;
        System.out.println(a > b); //true
        System.out.println(a >= b); //true
        System.out.println(a <= b); //false
        System.out.println(a < b);//false
        System.out.println(a == b); //false
        System.out.println(a != b); //true
        boolean flag = a > b; //true
        System.out.println("flag=" + flag);//true


    }
}

/*
 * 逻辑运算符介绍:
 * 1.用于连接多个条件（多个关系表达式），最终的结果也是一个 boolean 值。
 * 2.概览
 * &&　　短路与
 * ||   短路或
 * !    取反
 * &    逻辑与
 * |    逻辑或
 * ^    逻辑异或
 *
 * 说明逻辑运算规则：
 * 1) a&b : & 叫逻辑与：规则：当 a 和 b 同时为 true ,则结果为 true, 否则为 false
 * 2) a&&b : && 叫短路与：规则：当 a 和 b 同时为 true ,则结果为 true,否则为 false
 * 3) a|b : | 叫逻辑或，规则：当 a 和 b ，有一个为 true ,则结果为 true,否则为 false
 * 4) a||b : || 叫短路或，规则：当 a 和 b ，有一个为 true ,则结果为 true,否则为 false
 * 5) !a : 叫取反，或者非运算。当 a 为 true, 则结果为 false, 当 a 为 false 是，结果为 true
 * 6) a^b: 叫逻辑异或，当 a 和 b 不同时，则结果为 true, 否则为 false
 *
 * && 和 & 基本规则:
 * 名称        语法                  特点
 * 短路与&&    条件 1&&条件 2         相同　：条件 1&&条件 2 两个条件都为 true，结果为 true,否则 false.
 *                                 区别　：对于&&短路与而言，如果第一个条件为 false ,后面的条件不再判断.
 * 逻辑与&     条件 1&条件 2          相同　：条件 1&条件 2 两个条件都为 true，结果为 true,否则 false.
 *                                 区别　：对于&逻辑与而言，如果第一个条件为 false ,后面的条件仍然会判断．
 *
 * || 和 | 基本规则
 * 名称        语法                  特点
 * 短路或||    条件 1||条件 2         相同　：只要有一个条件成立，结果为 true,否则为 false.
 *                                  区别　：对于||短路与而言，如果第一个条件为 false ,后面的条件不再判断.
 * |逻辑或     条件 1|条件 2          相同　：只要有一个条件成立，结果为 true,否则为 false
 *                                  区别　：对于|逻辑与而言，如果第一个条件为 false ,后面的条件仍然会判断
 *
 * ! 取反 基本规则
 * 名称        语法                  特点
 * ! 非（取反） !条件                 如果条件本身成立，结果为 false，否则为 true
 *
 *
 * */

class LogicalOperator {
    //&&短路与 和 & 案例演示
    public static void demo() {

        int age = 50;
        if (age > 20 && age < 90) {
            System.out.println("&&短路与-ok" + "age=" + age);
        }
        //&逻辑与使用
        if (age > 20 & age < 90) {
            System.out.println("&逻辑-ok" + "age=" + age);
        }

        //区别
        int a = 4;
        int b = 9;
        //对于&&短路与而言，如果第一个条件为 false ,后面的条件不再判断
        //对于&逻辑与而言，如果第一个条件为 false ,后面的条件仍然会判断
        if (a < 1 & ++b < 50) {
            System.out.println("ok300");
        }
        System.out.println("a=" + a + " b=" + b);// 4 10
        int aa = 4;
        int bb = 9;
        if (aa < 1 && ++bb < 50) {
            System.out.println("ok300");
        }
        System.out.println("a=" + aa + " bb=" + bb);// 4 9

    }


    //||短路或 和 |　逻辑或 案例演示
    public static void demo1() {
        // (1)||短路或：如果第一个条件为 true，则第二个条件不会判断，最终结果为 true，效率高
        // (2)| 逻辑或：不管第一个条件是否为 true，第二个条件都要判断，效率低

        int a = 4;
        int b = 9;
        if (a > 1 || ++b > 4) {
            // 可以换成 | 测试
            System.out.println("ok300");
        }
        System.out.println("a=" + a + " b=" + b);//4 10
        int aa = 4;
        int bb = 9;
        if (aa > 1 || ++bb > 4) {
            // 可以换成 | 测试
            System.out.println("ok300");
        }
        System.out.println("aa=" + aa + " bb=" + bb);//4 9
    }

    //!和^案例演示
    public static void InverseOperator() {
        //! 操作是取反 T->F , F -> T
        System.out.println(60 > 20); //T
        System.out.println(!(60 > 20)); //F
        //a^b: 叫逻辑异或，当 a 和 b 不同时，则结果为 true, 否则为 false
        boolean b = (10 > 1) ^ (3 > 5);
        System.out.println("b=" + b);//T
        System.out.println((4 < 1) ^ (6 > 3)); // T


    }
}


/*
 * 赋值运算符
 * 基本赋值运算符
 * = int a = 10
 * 复合赋值运算符
 * += ，-= ，*= ， /= ，%= 等 , 重点讲解一个 += ，其它的使用是一个道理
 * a += b; [等价 a = a + b; ]
 * a -= b; [等价 a = a - b; ]
 * */

class AssignOperator {
    public static void dome() {
        int n1 = 10;
        n1 += 4;// n1 = n1 + 4;
        System.out.println(n1); // 14
        n1 /= 3;// n1 = n1 / 3;//4
        System.out.println(n1); // 4
        //复合赋值运算符会进行类型转换
        byte b = 3;
        b += 2; // 等价 b = (byte)(b + 2);
        b++; // b = (byte)(b+1);
    }
}


/*
 * 三元运算符
 * 基本语法
 * 条件表达式 ? 表达式 1: 表达式 2;
 * 运算规则：
 * 1. 如果条件表达式为 true，运算后的结果是表达式 1；
 * 2. 如果条件表达式为 false，运算后的结果是表达式 2；
 *
 * */

//三元运算符使用
class TernaryOperator {
    public static void dome() {
        int a = 10;
        int b = 99;
        // 解读
        // 1. a > b 为 false
        // 2. 返回 b--, 先返回 b 的值,然后在 b-1
        // 3. 返回的结果是 99
        int result = a > b ? a++ : b--;
        System.out.println("result=" + result);//99
        System.out.println("a=" + a); //10
        System.out.println("b=" + b); //98
    }

    //三元运算符细节
    public static void Detail() {
        //表达式 1 和表达式 2 要为可以赋给接收变量的类型
        //(或可以自动转换/或者强制转换)
        int a = 3;
        int b = 8;
        int c = a > b ? (int) 1.1 : (int) 3.4;//可以的
        double d = a > b ? a : b + 3;//可以的，满足 int -> double
        System.out.println("c=" + c); //3
        System.out.println("d=" + d); //11.0
    }

    //课堂练习 实现三个数的最大值
    public static void Exercise() {
        int n1 = 553;
        int n2 = 33;
        int n3 = 123;
        //思路 //1. 先得到 n1 和 n2 中最大数 , 保存到 max1
        // 2. 然后再 求出 max1 和 n3 中的最大数，保存到 max2
        int max1 = n1 > n2 ? n1 : n2;
        int max2 = max1 > n3 ? max1 : n3;
        System.out.println("最大数=" + max2);

        //使用一条语句实现, 推荐使用上面方法
        int max = (n1 > n2 ? n1 : n2) > n3 ? (n1 > n2 ? n1 : n2) : n3;
        System.out.println("最大数=" + max); //

    }
}